package com.cjm.one.common.config.jackson.converter;
import com.cjm.one.model.base.BaseEnum;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.Arrays;

//枚举反序列化
@Slf4j
public class BaseEnumDeserializer extends JsonDeserializer<BaseEnum> implements ContextualDeserializer {
    private Class<? extends BaseEnum> propertyClass; // 记录枚举字段的类，用于获取其定义的所有枚举值

    public BaseEnumDeserializer() {
        log.info("Construct with no args"); // 必须有无参构造器，spring会调用
    }

    public BaseEnumDeserializer(Class<? extends BaseEnum> propertyClass) {
        log.info("Construct with property class: {}", propertyClass);
        this.propertyClass = propertyClass;
    }
    private <E extends BaseEnum> E findEnumByCode(Class<E> enumClass, String codeValue) {
        return Arrays.stream(enumClass.getEnumConstants())
                .filter(e -> String.valueOf(e.getCode()).equals(codeValue))
                .findFirst()
                .orElseGet(() -> findDefaultEnum(enumClass));
    }

    private <E extends BaseEnum> E findDefaultEnum(Class<E> enumClass) {
        return Arrays.stream(enumClass.getEnumConstants())
                .filter(e -> e.getClass().isAnnotationPresent(JsonEnumDefaultValue.class))
                .findFirst()
                .orElse(null);
    }
    @Override
    public BaseEnum deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String codeValue = p.getText();
        // 通过泛型方法保持类型一致性
        return findEnumByCode(propertyClass, codeValue);
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext deserializationContext, BeanProperty beanProperty) throws JsonMappingException {
        log.info("Construct with property class");
        return new BaseEnumDeserializer((Class<? extends BaseEnum>) beanProperty.getType().getRawClass()); // 获取枚举字段的类型Class
    }
}